package com.njtoyo.taxi.admin.service.data.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.library.CommUtil;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoArea;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverMapper;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.DriverKpi;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.data.DriverKpiMapper;
import com.njtoyo.taxi.admin.rest.export.driver.DriverAppraiseData;
import com.njtoyo.taxi.admin.rest.presenter.data.data_analysis.DriverDataPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.data.data_analysis.DriverDataWrapper;
import com.njtoyo.taxi.admin.service.data.DriverKpiService;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.taxi.entity.common.RestResult;
import lombok.SneakyThrows;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DriverKpiServiceImpl implements DriverKpiService {
    @Autowired
    DriverKpiMapper driverKpiMapper;

    @Autowired
    DriverMapper driverMapper;

    @Override
    public RestResult list(AdminUser adminUser, DriverDataWrapper wrapper) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();
        switch (adminUser.getAccountType()) {
            case canton:
                wrapper.setCantonIds(identity.getCantonIds());
                break;
            case company:
                wrapper.setCompanyIds(identity.getCompanyIds());
        }
        Page<Long> driverKpiPage = driverMapper.getDriverIdPage(wrapper);
        Page<DriverDataPresenter> pageVO = new Page<>();
        if (CollUtil.isNotEmpty(driverKpiPage.getRecords())) {
            List<Long> driverIds = driverKpiPage.getRecords();
            if (ObjectUtil.isNull(wrapper.getStartDate()) || ObjectUtil.isNull(wrapper.getEndDate())) {
                wrapper.setStartDate(DateUtil.offsetDay(DateUtil.date(), -30).toDateStr());
                wrapper.setEndDate(DateUtil.date().toDateStr());
            }
            List<DriverDataPresenter> res = driverKpiMapper.getDriverKpiList(driverIds, wrapper.getStartDate(), wrapper.getEndDate());
            int i = (int) ((wrapper.getCurrent() - 1) * wrapper.getSize() + 1);
            for (DriverDataPresenter presenter : res) {
                presenter.setNo(i++);
                presenter.setEndRateStr(CommUtil.rateStr(CommUtil.div(presenter.getEndNum(), presenter.getCallNum())));
                DriverKpi driverKpi = driverKpiMapper.selectOne(Wrappers.<DriverKpi>lambdaQuery()
                        .eq(DriverKpi::getDriverId, presenter.getDriverId())
                        .orderByDesc(DriverKpi::getId).last("limit 1"));
                presenter.setDriverName(driverKpi.getDriverName());
                presenter.setCompanyName(driverKpi.getCompanyName());
                presenter.setCantonName(driverKpi.getCantonName());
                presenter.setIsLeave(driverKpi.getDriverStatus());
            }
            pageVO.setRecords(res);
            pageVO.setTotal(driverKpiPage.getTotal());
            pageVO.setPages(driverKpiPage.getPages());
            pageVO.setSize(driverKpiPage.getSize());
            pageVO.setCurrent(wrapper.getCurrent());
        }
        return RestResult.success(pageVO);
    }

    @SneakyThrows
    @Override
    public void driverDataExport(AdminUser adminUser, DriverDataWrapper wrapper, HttpServletResponse response) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();
        switch (adminUser.getAccountType()) {
            case canton:
                wrapper.setCantonIds(identity.getCantonIds());
                break;
            case company:
                wrapper.setCompanyIds(identity.getCompanyIds());
        }
        if (ObjectUtil.isNull(wrapper.getStartDate()) || ObjectUtil.isNull(wrapper.getEndDate())) {
            wrapper.setStartDate(DateUtil.offsetDay(DateUtil.date(), -30).toDateStr());
            wrapper.setEndDate(DateUtil.date().toDateStr());
        }
        wrapper.setCurrent(1L);
        wrapper.setSize(Integer.MAX_VALUE);
        Page<DriverDataPresenter> res = driverKpiMapper.getDriverDateList(wrapper);
        int i = (int) ((wrapper.getCurrent() - 1) * wrapper.getSize() + 1);
        List<DriverAppraiseData> rows = new ArrayList<>();
        if (CollUtil.isNotEmpty(res.getRecords())) {
            for (DriverDataPresenter record : res.getRecords()) {
                DriverAppraiseData row = new DriverAppraiseData();
                row.setDriverName(record.getDriverName());
                row.setPlateNumber(record.getPlateNumber());
                row.setCantonName(record.getCantonName());
                row.setCompanyName(record.getCompanyName());
                row.setMarkScore(record.getMarkScore());
                row.setIncome(record.getIncome());
                row.setCallNum(record.getCallNum());
                row.setEndNum(record.getEndNum());
                row.setEndRateStr(CommUtil.rateStr(CommUtil.div(row.getEndNum(), row.getCallNum())));
                row.setDriverCancel(record.getDriverCancel());
                row.setCustomerCancel(record.getCustomerCancel());
                row.setFiveMake(record.getFiveMake());
                row.setRecommend(record.getRecommend());
                row.setConfirmCall(record.getConfirmCall());

                rows.add(row);
            }
            ExcelWriter writer = ExcelUtil.getWriter();
            StyleSet style = writer.getStyleSet();
            CellStyle cellStyle = style.getHeadCellStyle();
            cellStyle.setWrapText(true);
            //自定义标题别名
            writer.addHeaderAlias("driverName", "司机名称");
            writer.addHeaderAlias("plateNumber", "车牌号");
            writer.addHeaderAlias("cantonName", "城市");
            writer.addHeaderAlias("companyName", "公司");
            writer.addHeaderAlias("markScore", "阳光分");
            writer.addHeaderAlias("income", "收入");
            writer.addHeaderAlias("confirmCall", "听单量");
            writer.addHeaderAlias("callNum", "应答量");
            writer.addHeaderAlias("endNum", "完单量");
            writer.addHeaderAlias("endRateStr", "完单率");
            writer.addHeaderAlias("driverCancel", "应答后司机取消量");
            writer.addHeaderAlias("customerCancel", "应答后乘客取消量");
            writer.addHeaderAlias("fiveMake", "五星好评");
            writer.addHeaderAlias("recommend", "推广数");
            writer.write(rows, true);
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=cars.xls");
            ServletOutputStream out = response.getOutputStream();

            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        }
    }
}
